package com.ruoyi.project.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.common.utils.HttpUtil;
import com.ruoyi.common.constant.WxOpenConstants;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.crm.domain.CrmSuncode;
import com.ruoyi.project.crm.mapper.CrmSuncodeMapper;
import com.ruoyi.project.file.service.OssService;
import com.ruoyi.project.wechat.domain.WxTwoCode;
import com.ruoyi.project.wechat.domain.XcxVersion;
import com.ruoyi.project.wechat.domain.XcxVersionExample;
import com.ruoyi.project.wechat.service.WxOpenLoginConfigService;
import com.ruoyi.project.wechat.service.XcxVersionService;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.open.api.WxOpenComponentService;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import me.chanjar.weixin.open.api.WxOpenMaService;
import me.chanjar.weixin.open.bean.ma.WxOpenMaSubmitAudit;
import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage;
import me.chanjar.weixin.open.bean.result.*;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 审核列表
 */
@RestController
@RequestMapping("/wechat/examine")
public class WxExamineController extends BaseController {

    @Resource
    private XcxVersionService xcxVersionService;

    @Resource
    private WxOpenComponentService wxOpenComponentService;

    @Resource
    private RedisCache redisCache;

    @Resource
    private OssService ossService;

    @Resource
    private WxOpenConfigStorage wxOpenConfigStorage;

    @Resource
    private WxOpenLoginConfigService wxOpenLoginConfigService;

    @Resource
    private  WxTwoCode wxTwoCodeConfig;

    @Resource
    private CrmSuncodeMapper crmSuncodeMapper;



    /**
     * 获取审核列表
     */
    @PreAuthorize("@ss.hasPermi('wechat:examine:list')")
    @GetMapping("/list")
    public TableDataInfo list(){
        startPage();
        XcxVersionExample example = new XcxVersionExample();
        example.setOrderByClause("id desc");
        List<XcxVersion> xcxVersionList = xcxVersionService.selectByExample(example);
        return getDataTable(xcxVersionList);
    }

    /**
     * 将第三方提交的代码包提交审核
     * @param xcxVersion
     * @return
     */
    @PreAuthorize("@ss.hasPermi('wechat:examine:submit')")
    @PostMapping("/submitAudit")
    public AjaxResult submitAudit(@RequestBody XcxVersion xcxVersion) throws WxErrorException {
        logger.info("将第三方提交的代码包提交审核 appId: "+xcxVersion.getAppId());
        String appId = xcxVersion.getAppId();
        WxOpenMaSubmitAuditMessage auditMessage = new WxOpenMaSubmitAuditMessage();
        WxOpenMaService service = wxOpenComponentService.getWxMaServiceByAppid(appId);

        //获取accessToken accessToken 缓存redis

        String accessToken = redisCache.getCacheObject(WxOpenConstants.CACHE_ACCESS_TOKEN);
        if(StringUtils.isEmpty(accessToken)){
            getAccessToken(appId);
        }
        //获取页面配置信息
        WxOpenMaPageListResult pageList = service.getPageList();
        WxOpenMaSubmitAudit audit = new WxOpenMaSubmitAudit();
        if(pageList.getPageList().size() > 0){
            audit.setPagePath(pageList.getPageList().get(0));
            List<WxOpenMaSubmitAudit> auditList = new ArrayList<WxOpenMaSubmitAudit>();
            auditList.add(audit);
            auditMessage.setItemList(auditList);
        }


        WxOpenMaSubmitAuditResult wxOpenMaSubmitAuditResult = service.submitAudit(auditMessage);
        XcxVersion version = xcxVersionService.selectByPrimaryKey(xcxVersion.getId());
        //修改入表
        version.setUpdateTime(new Date());
        version.setUpdateBy(SecurityUtils.getUsername());
        version.setErrCode(wxOpenMaSubmitAuditResult.getErrcode());
        version.setErrMsg(wxOpenMaSubmitAuditResult.getErrmsg());
        version.setAuditId(wxOpenMaSubmitAuditResult.getAuditId().toString());
        xcxVersionService.updateByPrimaryKey(version);
        return AjaxResult.success(wxOpenMaSubmitAuditResult);
    }

    /**
     * 获取体验码
     */
    @PreAuthorize("@ss.hasPermi('wechat:examine:file')")
    @GetMapping("/getTestQrcode")
    public AjaxResult getTestQrcode(@RequestParam String appId) throws WxErrorException, IOException {
        WxOpenMaService service = wxOpenComponentService.getWxMaServiceByAppid(appId);
        File testQrcode = service.getTestQrcode("",null);
        FileItem fildName = FileUtils.createFileItem(testQrcode, "fildName");
        MultipartFile multipartFile = new CommonsMultipartFile(fildName);
        return ossService.upload(multipartFile);
    }


    /**
     * 发布已通过审核的小程序
     * @param appId
     * @return
     */
    @PreAuthorize("@ss.hasPermi('wechat:examine:releaes')")
    @PostMapping("/releaesAudited")
    public AjaxResult releaesAudited(@RequestParam String appId) throws WxErrorException {
        logger.info("发布已通过审核的小程序 appId: "+appId);
        WxOpenMaService service = wxOpenComponentService.getWxMaServiceByAppid(appId);
        WxOpenResult wxOpenResult = service.releaesAudited();
        return AjaxResult.success(wxOpenResult);
    }

    /**
     * 加急审核申请
     * 有加急次数的第三方可以通过该接口，对已经提审的小程序进行加急操作，加急后的小程序预计2-12小时内审完。
     */
    @PostMapping("/speedAudit")
    public AjaxResult speedAudit(@RequestParam String appId, @RequestParam Long auditid) throws WxErrorException {
        logger.info("加急审核申请 appId: "+appId);
        WxOpenMaService service = wxOpenComponentService.getWxMaServiceByAppid(appId);
        Boolean aBoolean = service.speedAudit(auditid);
        return AjaxResult.success(aBoolean);
    }

    /**
     * 查询某个指定版本的审核状态
     * @param appId
     * @return
     */
    @PostMapping("/getAuditStatus")
    public AjaxResult getAuditStatus(@RequestParam String appId, @RequestParam Long auditId) throws WxErrorException {
        logger.info("查询某个指定版本的审核状态 appId: "+appId);
        WxOpenMaService service = wxOpenComponentService.getWxMaServiceByAppid(appId);
        WxOpenMaQueryAuditResult auditStatus = service.getAuditStatus(auditId);
        return AjaxResult.success(auditStatus);
    }

    /**
     * 查询最新一次提交的审核状态
     * @param appId
     * @return
     */
    @PostMapping("/getLatestAuditStatus")
    public AjaxResult getLatestAuditStatus(@RequestParam String appId) throws WxErrorException {
        logger.info("查询最新一次提交的审核状态 appId: "+appId);
        WxOpenMaService service = wxOpenComponentService.getWxMaServiceByAppid(appId);
        WxOpenMaQueryAuditResult auditStatus = service.getLatestAuditStatus();
        return AjaxResult.success(auditStatus);
    }

    /**
     * 获取token
     * @return
     */
    public void getAccessToken(String appId) throws WxErrorException {
        //查询微信信息
        WxOpenAuthorizerInfoResult authorizerInfo = wxOpenComponentService.getAuthorizerInfo(appId);
        String authorizerAccessToken = authorizerInfo.getAuthorizationInfo().getAuthorizerAccessToken();
        redisCache.setCacheObject(WxOpenConstants.CACHE_ACCESS_TOKEN,authorizerAccessToken,7200, TimeUnit.SECONDS);
    }

    /**
     * 获取token
     * @return
     */
    @PostMapping("/getWxTwoCode")
    public AjaxResult getWxTwoCode(@RequestBody WxTwoCode wxTwoCode) throws WxErrorException {

        /*1.0获取access_token*/
        //获取appid
        String appId = wxTwoCodeConfig.getUserappid();
//        String appId = "wx3058c36af729fb57";

        //查询当前ID是否已经生成二维码，生成则直接返回，否则从新生成在返回
        CrmSuncode crmSuncode = new CrmSuncode();
        crmSuncode.setScene(wxTwoCode.getScene());
        List<CrmSuncode> listcsc = crmSuncodeMapper.selectCrmSuncodeList(crmSuncode);

        if (listcsc.size() < 1){

            //获取用户token信息
            WxOpenAuthorizerInfoResult authorizerInfo = wxOpenComponentService.getAuthorizerInfo(appId);
            String authorizerAccessToken = authorizerInfo.getAuthorizationInfo().getAuthorizerAccessToken();
            //authorizerAccessToken 为null则获取 authorizerAccessToken
            if (null == authorizerAccessToken){
                String authorizerRefreshToken = authorizerInfo.getAuthorizationInfo().getAuthorizerRefreshToken();
                wxOpenConfigStorage.setAuthorizerRefreshToken(appId,authorizerRefreshToken);
//            authorizerAccessToken = "34_LHqgCpo0IBB27Q0FsTL4MR6MSbR_DnIsTq8J9QaKrFFmudiVzCPa6UP-UPAQT9BfVKl3s2hfLYQoh2RtlU2RSepOMYE9dudtlwmrD960MVCThdaAkATdAk-t__ZNdSwg-5aC8gihT4GV2sDTMHIiAGDTOP";
                authorizerAccessToken = wxOpenLoginConfigService.getAuthorizerToken(appId);
            }
            System.out.println("---------authorizerAccessToken:"+authorizerAccessToken);
//        redisCache.setCacheObject(WxOpenConstants.CACHE_ACCESS_TOKEN,authorizerAccessToken,7200, TimeUnit.SECONDS);

            /*2.0调用微信端接口，获取二维码*/
//        Map<String,Object> paramsMap=new HashMap<String,Object>();
//        paramsMap.put("scene", wxTwoCode.getScene());
//        paramsMap.put("password", wxTwoCodeConfig.getUserpage());
//        paramsMap.put("password", wxTwoCodeConfig.getUserwidth());

//        HttpUtil.post(wxTwoCodeConfig.getUserurl()+authorizerAccessToken,paramsMap);
            //设置请求头
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            //请求参数
            JSONObject requestEntityParam = new JSONObject();
            requestEntityParam.put("scene",wxTwoCode.getScene());
            requestEntityParam.put("page", wxTwoCodeConfig.getUserpage());
            //封装
            HttpEntity<String> requestEntity = new HttpEntity(requestEntityParam, headers);
            System.out.println("生成太阳码请求url参数:"+ wxTwoCodeConfig.getUserurl() + authorizerAccessToken);
            System.out.println("生成太阳码其他参数:"+JSON.toJSONString(requestEntity));
            //获取二维码图片
            ResponseEntity<byte[]> entity = restTemplate.exchange(wxTwoCodeConfig.getUserurl() + authorizerAccessToken, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            byte[] result = entity.getBody();
            //转换图片名称
            InputStream inputStream = new ByteArrayInputStream(result);
            String filename = System.currentTimeMillis() + ".png";
            //存储图片至OSS
            String url = ossService.getOssUrl() +ossService.uploadObjectOSS(new File(filename), inputStream);
            System.out.println("生成图片详细地址:"+url);

            crmSuncode.setUserpage(wxTwoCodeConfig.getUserpage());
            crmSuncode.setUserurl(url);
            crmSuncodeMapper.insertCrmSuncode(crmSuncode);
            List<CrmSuncode> listcscisnot = crmSuncodeMapper.selectCrmSuncodeList(crmSuncode);
            CrmSuncode rescsc = listcscisnot.get(0);
            return AjaxResult.success(rescsc);

        }else {
            CrmSuncode rescsc = listcsc.get(0);
            return AjaxResult.success(rescsc);
        }
    }



}
